home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / x11 / rpg / crossfir.92 / crossfir / crossfire-0.92.5 / common / time.c < prev    next >
C/C++ Source or Header  |  1996-07-24  |  7KB  |  254 lines

  1. /*
  2.  * static char *rcsid_time_c =
  3.  *    "$Id: time.c,v 1.11 1996/03/04 09:25:10 master Exp $";
  4.  */
  5.  
  6. /*
  7.     CrossFire, A Multiplayer game for X-windows
  8.  
  9.     Copyright (C) 1994 Mark Wedel
  10.     Copyright (C) 1992 Frank Tore Johansen
  11.  
  12.     This program is free software; you can redistribute it and/or modify
  13.     it under the terms of the GNU General Public License as published by
  14.     the Free Software Foundation; either version 2 of the License, or
  15.     (at your option) any later version.
  16.  
  17.     This program is distributed in the hope that it will be useful,
  18.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  19.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20.     GNU General Public License for more details.
  21.  
  22.     You should have received a copy of the GNU General Public License
  23.     along with this program; if not, write to the Free Software
  24.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  25.  
  26.     The author can be reached via e-mail to master@rahul.net
  27. */
  28.  
  29. #include <stdio.h>
  30. #include <sys/types.h>
  31. #include <sys/time.h>
  32. #include <global.h>
  33. #include <funcpoint.h>
  34.  
  35.  
  36. /*
  37.  * Gloabal variables:
  38.  */
  39. long max_time = MAX_TIME;
  40. struct timeval last_time;
  41.  
  42. #ifdef DEBUG_TIME
  43. #define PBUFLEN 100
  44. long process_utime_save[PBUFLEN];
  45. long psaveind;
  46. long process_max_utime = 0;
  47. long process_min_utime = 999999999;
  48. long process_tot_mtime;
  49. long pticks;
  50. long process_utime_long_count;
  51. #endif
  52.  
  53. /* Solaris 2.5 wants 2 arguments for gettimeofday - fake it out here until
  54.  * I can determine if earlier version of solaris do in fact only have 1
  55.  * argument.
  56.  */
  57. #if defined(__sun__) && defined(SVR4)
  58. #define gettimeofday(last_time) gettimeofday(last_time, (struct timezone *) NULL);
  59. #endif
  60.  
  61. /*
  62.  * Initialise all variables used in the timing routines. 
  63.  */
  64.  
  65. void
  66. reset_sleep()
  67. {
  68. #ifdef DEBUG_TIME
  69.   int i;
  70.   for(i = 0; i < PBUFLEN; i++)
  71.     process_utime_save[i] = 0;
  72.   psaveind = 0;
  73.   process_max_utime = 0;
  74.   process_min_utime = 999999999;
  75.   process_tot_mtime = 0;
  76.   pticks = 0;
  77. #endif
  78.  
  79. #if defined(__sun__) && defined(SVR4)
  80.   (void) gettimeofday(&last_time);
  81. #else
  82.   (void) gettimeofday(&last_time, (struct timezone *) NULL);
  83. #endif
  84. }
  85.  
  86. void
  87. log_time(long process_utime)
  88. {
  89. #ifdef DEBUG_TIME
  90.   pticks++;
  91.   if (++psaveind >= PBUFLEN)
  92.     psaveind = 0;
  93.   process_utime_save[psaveind] = process_utime;
  94.   if (process_utime > process_max_utime)
  95.     process_max_utime = process_utime;
  96.   if (process_utime < process_min_utime)
  97.     process_min_utime = process_utime;
  98.   process_tot_mtime += process_utime/1000;
  99. #endif
  100. }
  101.  
  102. /*
  103.  * enough_elapsed_time will return true if the time passed since
  104.  * last tick is more than max-time.
  105.  */
  106.  
  107. int
  108. enough_elapsed_time()
  109. {
  110.   static struct timeval new_time;
  111.   long elapsed_utime;
  112.  
  113. #if defined(__sun__) && defined(SVR4)
  114.   (void) gettimeofday(&new_time);
  115. #else
  116.   (void) gettimeofday(&new_time, (struct timezone *) NULL);
  117. #endif
  118.   elapsed_utime = (new_time.tv_sec - last_time.tv_sec) * 1000000 +
  119.                   new_time.tv_usec - last_time.tv_usec;
  120.   if (elapsed_utime > max_time) {
  121. #ifdef DEBUG_TIME
  122.     log_time(elapsed_utime);
  123. #endif
  124.     last_time.tv_sec = new_time.tv_sec;
  125.     last_time.tv_usec = new_time.tv_usec;
  126.     return 1;
  127.   }
  128.   return 0;
  129. }
  130.  
  131. /*
  132.  * sleep_delta checks how much time has elapsed since last tick.
  133.  * If it is less than max_time, the remaining time is slept with select().
  134.  */
  135.  
  136. void
  137. sleep_delta()
  138. {
  139.   static struct timeval new_time;
  140.   long sleep_sec, sleep_usec;
  141.  
  142. #if defined(__sun__) && defined(SVR4)
  143.   (void) gettimeofday(&new_time);
  144. #else
  145.   (void) gettimeofday(&new_time, (struct timezone *) NULL);
  146. #endif
  147.   sleep_sec = last_time.tv_sec - new_time.tv_sec;
  148.   sleep_usec = max_time - (new_time.tv_usec - last_time.tv_usec);
  149.  
  150.   /* This is very ugly, but probably the fastest for our use: */
  151.   while (sleep_usec < 0) {
  152.     sleep_usec += 1000000;
  153.     sleep_sec -= 1;
  154.   }
  155.   while (sleep_usec > 1000000) {
  156.     sleep_usec -= 1000000;
  157.     sleep_sec +=1;
  158.   }
  159.  
  160. #ifdef DEBUG_TIME
  161.   log_time((new_time.tv_sec - last_time.tv_sec)*1000000
  162.            + new_time.tv_usec - last_time.tv_usec);
  163. #endif
  164.  
  165.   if (sleep_sec >= 0 && sleep_usec > 0) {
  166.     static struct timeval sleep_time;
  167.     sleep_time.tv_sec = sleep_sec;
  168.     sleep_time.tv_usec = sleep_usec;
  169.     select(0, NULL, NULL, NULL, &sleep_time);
  170.   }
  171. #ifdef DEBUG_TIME
  172.   else
  173.     process_utime_long_count++;
  174. #endif
  175.   /*
  176.    * Set last_time to when we're expected to wake up:
  177.    */
  178.   last_time.tv_usec += max_time;
  179.   while (last_time.tv_usec > 1000000) {
  180.     last_time.tv_usec -= 1000000;
  181.     last_time.tv_sec++;
  182.   }
  183.   /*
  184.    * Don't do too much catching up:
  185.    * (Things can still get jerky on a slow/loaded computer)
  186.    */
  187.   if (last_time.tv_sec * 1000000 + last_time.tv_usec <
  188.       new_time.tv_sec * 1000000 + new_time.tv_usec)
  189.   {
  190.     last_time.tv_sec = new_time.tv_sec;
  191.     last_time.tv_usec = new_time.tv_usec;
  192.   }
  193. }
  194.  
  195. void
  196. set_max_time(long t) {
  197.   max_time = t;
  198. }
  199.  
  200. void
  201. time_info(object *op)
  202. {
  203. #ifdef DEBUG_TIME
  204.   int tot = 0, maxt = 0, mint = 99999999, long_count = 0, i;
  205.  
  206.   (*draw_info_func) (NDI_UNIQUE, 0,op,"Total time:");
  207.   sprintf(errmsg,"ticks=%ld  time=%ld.%2ld",
  208.           pticks, process_tot_mtime/1000, process_tot_mtime%1000);
  209.   (*draw_info_func) (NDI_UNIQUE, 0,op,errmsg);
  210.   sprintf(errmsg,"avg time=%ldms  max time=%ldms  min time=%ldms",
  211.           process_tot_mtime/pticks, process_max_utime/1000,
  212.           process_min_utime/1000);
  213.   (*draw_info_func) (NDI_UNIQUE, 0,op,errmsg);
  214.   sprintf(errmsg,"ticks longer than max time (%ldms) = %ld (%ld%%)",
  215.           max_time/1000,
  216.           process_utime_long_count, 100*process_utime_long_count/pticks);
  217.   (*draw_info_func) (NDI_UNIQUE, 0,op,errmsg);
  218.  
  219.   sprintf(errmsg,"Time last %ld ticks:", pticks > PBUFLEN ? PBUFLEN : pticks);
  220.   (*draw_info_func) (NDI_UNIQUE, 0,op,errmsg);
  221.  
  222.   for (i = 0; i < (pticks > PBUFLEN ? PBUFLEN : pticks); i++) {
  223.     tot += process_utime_save[i];
  224.     if (process_utime_save[i] > maxt) maxt = process_utime_save[i];
  225.     if (process_utime_save[i] < mint) mint = process_utime_save[i];
  226.     if (process_utime_save[i] > max_time) long_count++;
  227.   }
  228.  
  229.   sprintf(errmsg,"avg time=%ldms  max time=%dms  min time=%dms",
  230.           tot/(pticks > PBUFLEN ? PBUFLEN : pticks)/1000, maxt/1000,
  231.           mint/1000);
  232.   (*draw_info_func) (NDI_UNIQUE, 0,op,errmsg);
  233.   sprintf(errmsg,"ticks longer than max time (%ldms) = %d (%ld%%)",
  234.           max_time/1000, long_count,
  235.           100*long_count/(pticks > PBUFLEN ? PBUFLEN : pticks));
  236.   (*draw_info_func) (NDI_UNIQUE, 0,op,errmsg);
  237. #else
  238.   (*draw_info_func) (NDI_UNIQUE, 0,op,"Not compiled with time-debug info.");
  239. #endif
  240. }
  241.  
  242. long
  243. seconds()
  244. {
  245.   struct timeval now;
  246.  
  247. #if defined(__sun__) && defined(SVR4)
  248.   (void) gettimeofday(&now);
  249. #else
  250.   (void) gettimeofday(&now, (struct timezone *) 0);
  251. #endif
  252.   return now.tv_sec;
  253. }
  254.